package com.turnengine.client.global.game.command.set;

import static com.javabi.common.dependency.DependencyFactory.getDependency;

import com.javabi.command.IExecutableCommandResponse;
import com.javabi.command.errorcode.ErrorCodeException;
import com.javabi.command.executor.ICommandExecutorService;
import com.turnengine.client.global.game.bean.IGame;
import com.turnengine.client.global.game.bean.IGameDefinition;
import com.turnengine.client.global.game.bean.IGameHost;
import com.turnengine.client.global.game.bean.IGameInstance;
import com.turnengine.client.global.game.bean.IGameVersion;
import com.turnengine.client.global.game.command.GetGameById;
import com.turnengine.client.global.game.command.GetGameByName;
import com.turnengine.client.global.game.command.GetGameDefinition;
import com.turnengine.client.global.game.command.GetGameDefinitions;
import com.turnengine.client.global.game.command.GetGameDefinitionsByGameName;
import com.turnengine.client.global.game.command.GetGameHostById;
import com.turnengine.client.global.game.command.GetGameHostByName;
import com.turnengine.client.global.game.command.GetGameHosts;
import com.turnengine.client.global.game.command.GetGameInstanceById;
import com.turnengine.client.global.game.command.GetGameInstanceByName;
import com.turnengine.client.global.game.command.GetGameInstanceByNames;
import com.turnengine.client.global.game.command.GetGameInstances;
import com.turnengine.client.global.game.command.GetGameInstancesByGameName;
import com.turnengine.client.global.game.command.GetGameVersionById;
import com.turnengine.client.global.game.command.GetGameVersionByName;
import com.turnengine.client.global.game.command.GetGameVersions;
import com.turnengine.client.global.game.command.GetGames;
import com.turnengine.client.global.game.command.IGetGameById;
import com.turnengine.client.global.game.command.IGetGameByName;
import com.turnengine.client.global.game.command.IGetGameDefinition;
import com.turnengine.client.global.game.command.IGetGameDefinitions;
import com.turnengine.client.global.game.command.IGetGameDefinitionsByGameName;
import com.turnengine.client.global.game.command.IGetGameHostById;
import com.turnengine.client.global.game.command.IGetGameHostByName;
import com.turnengine.client.global.game.command.IGetGameHosts;
import com.turnengine.client.global.game.command.IGetGameInstanceById;
import com.turnengine.client.global.game.command.IGetGameInstanceByName;
import com.turnengine.client.global.game.command.IGetGameInstanceByNames;
import com.turnengine.client.global.game.command.IGetGameInstances;
import com.turnengine.client.global.game.command.IGetGameInstancesByGameName;
import com.turnengine.client.global.game.command.IGetGameVersionById;
import com.turnengine.client.global.game.command.IGetGameVersionByName;
import com.turnengine.client.global.game.command.IGetGameVersions;
import com.turnengine.client.global.game.command.IGetGames;
import com.turnengine.client.global.game.command.INewGame;
import com.turnengine.client.global.game.command.INewGameHost;
import com.turnengine.client.global.game.command.INewGameInstance;
import com.turnengine.client.global.game.command.INewGameVersion;
import com.turnengine.client.global.game.command.IResetGame;
import com.turnengine.client.global.game.command.IShutdownGame;
import com.turnengine.client.global.game.command.IStartupGame;
import com.turnengine.client.global.game.command.NewGame;
import com.turnengine.client.global.game.command.NewGameHost;
import com.turnengine.client.global.game.command.NewGameInstance;
import com.turnengine.client.global.game.command.NewGameVersion;
import com.turnengine.client.global.game.command.ResetGame;
import com.turnengine.client.global.game.command.ShutdownGame;
import com.turnengine.client.global.game.command.StartupGame;
import java.util.List;

/**
 * The Global Game Command Set.
 */
public class GlobalGameCommandSet implements IGlobalGameCommandSet {

	@Override
	public IGame newGame(long loginId, String name) {
		INewGame command = new NewGame(loginId, name);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGame> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGameVersion newGameVersion(long loginId, String gameName, String versionName) {
		INewGameVersion command = new NewGameVersion(loginId, gameName, versionName);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGameVersion> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGameInstance newGameInstance(long loginId, String gameName, String versionName, String instanceName, int hostId) {
		INewGameInstance command = new NewGameInstance(loginId, gameName, versionName, instanceName, hostId);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGameInstance> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGame getGameById(int gameId) {
		IGetGameById command = new GetGameById(gameId);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGame> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGame getGameByName(String gameName) {
		IGetGameByName command = new GetGameByName(gameName);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGame> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGameVersion getGameVersionById(int versionId) {
		IGetGameVersionById command = new GetGameVersionById(versionId);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGameVersion> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGameVersion getGameVersionByName(String versionName, int gameId) {
		IGetGameVersionByName command = new GetGameVersionByName(versionName, gameId);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGameVersion> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGameInstance getGameInstanceById(int instanceId) {
		IGetGameInstanceById command = new GetGameInstanceById(instanceId);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGameInstance> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGameInstance getGameInstanceByName(String instanceName, int versionId) {
		IGetGameInstanceByName command = new GetGameInstanceByName(instanceName, versionId);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGameInstance> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public List<IGame> getGames() {
		IGetGames command = new GetGames();
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<List<IGame>> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public List<IGameVersion> getGameVersions() {
		IGetGameVersions command = new GetGameVersions();
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<List<IGameVersion>> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public List<IGameInstance> getGameInstances() {
		IGetGameInstances command = new GetGameInstances();
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<List<IGameInstance>> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public List<IGameDefinition> getGameDefinitions() {
		IGetGameDefinitions command = new GetGameDefinitions();
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<List<IGameDefinition>> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGameDefinition getGameDefinition(int instanceId) {
		IGetGameDefinition command = new GetGameDefinition(instanceId);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGameDefinition> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public Boolean startupGame(long loginId, int instanceId) {
		IStartupGame command = new StartupGame(loginId, instanceId);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<Boolean> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public Boolean resetGame(long loginId, int instanceId) {
		IResetGame command = new ResetGame(loginId, instanceId);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<Boolean> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public Boolean shutdownGame(long loginId, int instanceId) {
		IShutdownGame command = new ShutdownGame(loginId, instanceId);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<Boolean> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGameHost newGameHost(long loginId, String name, int port) {
		INewGameHost command = new NewGameHost(loginId, name, port);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGameHost> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGameInstance getGameInstanceByNames(String gameName, String versionName, String instanceName) {
		IGetGameInstanceByNames command = new GetGameInstanceByNames(gameName, versionName, instanceName);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGameInstance> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGameHost getGameHostByName(String name, int port) {
		IGetGameHostByName command = new GetGameHostByName(name, port);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGameHost> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public IGameHost getGameHostById(int id) {
		IGetGameHostById command = new GetGameHostById(id);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<IGameHost> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public List<IGameHost> getGameHosts() {
		IGetGameHosts command = new GetGameHosts();
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<List<IGameHost>> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public List<IGameInstance> getGameInstancesByGameName(String gameName) {
		IGetGameInstancesByGameName command = new GetGameInstancesByGameName(gameName);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<List<IGameInstance>> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}

	@Override
	public List<IGameDefinition> getGameDefinitionsByGameName(String gameName) {
		IGetGameDefinitionsByGameName command = new GetGameDefinitionsByGameName(gameName);
		ICommandExecutorService service = getDependency(ICommandExecutorService.class);
		IExecutableCommandResponse<List<IGameDefinition>> response = service.execute(command);
		if (response.hasErrors()) {
			throw new ErrorCodeException(response);
		}
		return response.getReturnValue();
	}
}
